﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FeatureModelCore.FMInterface;
using Collections.TreeCollections;

namespace FeatureModelCore.FMCrossTreeConstraint
{
    public class FeatureTreeObjectExtension
    {
        public CrossTreeConstraintInfoForNode[] OuterConstraint { get { return getOuterConstraint(); } }
        public CrossTreeConstraintInfoForNode[] AllCrossTreeConstraints { get { return _consInfo.ToArray<CrossTreeConstraintInfoForNode>(); } }
        public CrossTreeConstraintInfoForNode this[TreeNodeIdentify index] { get { return getConsInfo(index); } }

        #region Fields
        private IFeatureTreeObject _obj;
        private List<CrossTreeConstraintInfoForNode> _consInfo;
        #endregion

        public FeatureTreeObjectExtension(IFeatureTreeObject obj)
        {
            _obj = obj;
            _consInfo = new List<CrossTreeConstraintInfoForNode>();
        }

        /// <summary>
        /// Add inner cross tree constraint
        /// </summary>
        /// <param name="cons"></param>
        /// <param name="nodeA"></param>
        /// <param name="nodeB"></param>
        internal CrossTreeConstraintInfoForNode addConstraint(IConstraint cons, IFeature nodeA
            , IFeature nodeB, CrossTreeConstraintInfoType type)
        {
            CrossTreeConstraintInfoForNode node = new CrossTreeConstraintInfoForNode(
                cons, nodeA, nodeB, type);
            _consInfo.Add(node);
            return node;
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="consId"></param>
        internal void removeConstaint(TreeNodeIdentify consId)
        {
            CrossTreeConstraintInfoForNode info = getConsInfo(consId);
            if (info != null)
                this._consInfo.Remove(info);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="consId"></param>
        /// <returns></returns>
        private CrossTreeConstraintInfoForNode getConsInfo(TreeNodeIdentify consId)
        {
            foreach (CrossTreeConstraintInfoForNode info in _consInfo)
            {
                if (info.CrossTreeConstraint.ID.Equals(consId))
                {
                    return info;
                }
            }
            return null;
        }

        /// <summary>
        /// Get outer constraint
        /// </summary>
        /// <returns></returns>
        private CrossTreeConstraintInfoForNode[] getOuterConstraint()
        {
            List<CrossTreeConstraintInfoForNode> consList = new List<CrossTreeConstraintInfoForNode>();
            foreach (CrossTreeConstraintInfoForNode cons in _consInfo)
            {
                if (cons.InfoType == CrossTreeConstraintInfoType.Outer)
                {
                    consList.Add(cons);
                }
            }
            return consList.ToArray<CrossTreeConstraintInfoForNode>();
        }
    }
}
